package com.toommi.refuse.service.impl;

import com.toommi.refuse.common.enums.RecyclableTrashTypeEnum;
import com.toommi.refuse.common.util.DateUtil;
import com.toommi.refuse.entity.*;
import com.toommi.refuse.enums.AdminExceptionEnum;
import com.toommi.refuse.enums.RecycleRecordExceptionEnum;
import com.toommi.refuse.exception.AdminException;
import com.toommi.refuse.exception.RecycleRecordException;
import com.toommi.refuse.mapper.BuildingMapper;
import com.toommi.refuse.mapper.HouseholdMapper;
import com.toommi.refuse.mapper.NeighbourhoodMapper;
import com.toommi.refuse.mapper.RecyclablePriceMapper;
import com.toommi.refuse.model.CalculateModel;
import com.toommi.refuse.model.RecyclablePriceModel;
import com.toommi.refuse.service.RecyclablePriceService;
import com.toommi.refuse.service.RefuseTypeService;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * @author yangg
 * @since 2019-07-31 11:49
 */
@Service
@AllArgsConstructor
public class RecyclablePriceServiceImpl implements RecyclablePriceService {

    private RefuseTypeService refuseTypeService;

    private NeighbourhoodMapper neighbourhoodMapper;

    private RecyclablePriceMapper recyclablePriceMapper;

    private HouseholdMapper householdMapper;

    private RecyclablePriceMapper priceMapper;

    private BuildingMapper buildingMapper;

    @Override
    public void addRecyclablePrice(RecyclablePrice recyclablePrice) throws AdminException {
        //校验参数合法性
        recyclablePrice.setId(0L);
        checkRecyclablePrice(recyclablePrice);

        //判断该小区是否已有该日期该类型的价格设置

        RecyclablePriceExample example = new RecyclablePriceExample();

        example.createCriteria().andDateEqualTo(recyclablePrice.getDate())
                .andRefuseTypeIdEqualTo(recyclablePrice.getRefuseTypeId())
                .andNeighbourhoodIdEqualTo(recyclablePrice.getNeighbourhoodId());
        RecyclablePrice price = recyclablePriceMapper.selectOneByExample(example);
        if (price != null) {
            //已存在，更新价格
            price.setUpdateTime(System.currentTimeMillis());
            price.setPrice(recyclablePrice.getPrice());
            recyclablePriceMapper.updateByPrimaryKey(price);
        } else {
            recyclablePrice.setCreateTime(System.currentTimeMillis());
            recyclablePrice.setUpdateTime(System.currentTimeMillis());
            recyclablePriceMapper.insert(recyclablePrice);
        }
    }

    @Override
    public List<RecyclablePriceModel> findRecyclablePrice(long refuseTypeId, long neighbourhoodId, String date) {

//        RecyclablePriceExample example = new RecyclablePriceExample();
//
//        RecyclablePriceExample.Criteria criteria = example.createCriteria();
//
//        if (refuseTypeId > 0) {
//            criteria.andRefuseTypeIdEqualTo(refuseTypeId);
//        }
//        if (neighbourhoodId > 0) {
//            criteria.andNeighbourhoodIdEqualTo(neighbourhoodId);
//        }
//        criteria.andDateEqualTo(date);

        List<RecyclablePrice> recyclablePriceList = recyclablePriceMapper.findRecyclablePrice(refuseTypeId,neighbourhoodId);
        List<RecyclablePriceModel> modelList = new ArrayList<>();
        if (recyclablePriceList != null && !recyclablePriceList.isEmpty()) {
            for (RecyclablePrice price : recyclablePriceList) {
                RecyclablePriceModel model = new RecyclablePriceModel();

                BeanUtils.copyProperties(price, model);

                String refuseTypeName = refuseTypeService.findDetail(price.getRefuseTypeId()).getName();
                String neighbourhoodName = neighbourhoodMapper.selectByPrimaryKey(price.getNeighbourhoodId()).getName();

                model.setNeighbourhoodName(neighbourhoodName);
                model.setRefuseTypeName(refuseTypeName);

                modelList.add(model);
            }
        }
        return modelList;
    }

    @Override
    public void updateRecyclablePrice(RecyclablePrice recyclablePrice) throws AdminException {
        checkRecyclablePrice(recyclablePrice);

        RecyclablePrice price = recyclablePriceMapper.selectByPrimaryKey(recyclablePrice.getId());
        if (price != null) {
            //已存在，更新价格
            price.setUpdateTime(System.currentTimeMillis());
            price.setPrice(recyclablePrice.getPrice());
            recyclablePriceMapper.updateByPrimaryKey(price);
        } else {
            throw new AdminException(AdminExceptionEnum.INVALID_RECYCLABLE_PRICE_NULL);
        }
    }

    @Override
    public CalculateModel calculateMoney(String qrcode, int subRefuseTypeId, double weight)
            throws RecycleRecordException {

        HouseholdExample householdExample = new HouseholdExample();
        householdExample.createCriteria().andCodeEqualTo(qrcode);
        Household household = householdMapper.selectOneByExample(householdExample);
        if (household == null) {
            throw new RecycleRecordException(RecycleRecordExceptionEnum.INVALID_HOUSEHOLDCODE_NULL);
        }
        Building building = buildingMapper.selectByPrimaryKey(household.getBuilding());

        RecyclablePrice recyclablePrice = new RecyclablePrice();
        recyclablePrice.setNeighbourhoodId(building.getNeighbourhood());
        recyclablePrice.setRefuseTypeId((long) subRefuseTypeId);
        recyclablePrice.setDate(DateUtil.formatTimestampToString(System.currentTimeMillis(), DateUtil.DATE_FORMAT_YMD));

        RecyclablePrice price = priceMapper.selectOne(recyclablePrice);

        if (price == null) {
            throw new RecycleRecordException(RecycleRecordExceptionEnum.INVALID_PRICE_NULL);
        }

        CalculateModel calculateModel = new CalculateModel();
        calculateModel.setPrice(price.getPrice().doubleValue());
        calculateModel.setQrcode(qrcode);
        calculateModel.setSubRefuseTypeId(subRefuseTypeId);
        calculateModel.setSubRefuseTypeName(RecyclableTrashTypeEnum.getType(subRefuseTypeId).getNote());
        calculateModel.setWeight(weight);
        calculateModel.setMoney(new BigDecimal(weight).multiply(price.getPrice()).setScale(2).doubleValue());

        return calculateModel;
    }

    /**
     * 校验基本参数合法性及真实性
     *
     * @param recyclablePrice 回收价格
     * @throws AdminException 校验异常
     */
    private void checkRecyclablePrice(RecyclablePrice recyclablePrice) throws AdminException {
        RefuseType refuseType = refuseTypeService.findDetail(recyclablePrice.getRefuseTypeId());
        if (refuseType == null) {
            //分类id标识错误
            throw new AdminException(AdminExceptionEnum.INVALID_RECYCLABLE_PRICE_TYPE_NULL);
        }

        Neighbourhood neighbourhood = neighbourhoodMapper.selectByPrimaryKey(recyclablePrice.getNeighbourhoodId());
        if (neighbourhood == null) {
            //小区id标识错误
            throw new AdminException(AdminExceptionEnum.INVALID_RECYCLABLE_PRICE_NEIGHBOURHOOD_NULL);
        }
        if (StringUtils.isEmpty(recyclablePrice.getDate())) {
            //日期错误
            throw new AdminException(AdminExceptionEnum.INVALID_RECYCLABLE_PRICE_DATE_NULL);
        }
    }
}
